package top.milkbox.core;

import java.util.*;

/**
 * 集合工具
 * @author milkbox
 */
public class UtilsColl {

    private static class Book {
        private String name;
        private int pages;

        public Book(String name, int pages) {
            this.name = name;
            this.pages = pages;
        }

        @Override
        public String toString() {
            return "Book{name='" + name + "', pages=" + pages + '}';
        }
    }

    public static void main(String[] args) {
        example1();
    }

    private static void example1() {
        List<Integer> list1 = Arrays.asList(1, 2, 3);
        List<String> list2 = Arrays.asList("A", "B");
        Set<String> set1 = new HashSet<>();
        set1.add("I");
        set1.add("II");
        set1.add("III");
        set1.add("VI");
        List<Book> list4 = Arrays.asList(
                new Book("高等数学", 88),
                new Book("Java从入门到入土", 100));

        List<List<Object>> reslutList = descartes(list1, list2, set1, list4);
        System.out.println(reslutList);
    }

    private static void example2() {
        List<Integer> list1 = Arrays.asList(1, 2, 3);
        List<String> list2 = Arrays.asList("A", "B");
        List<List<?>> mainList = new ArrayList<>();
        mainList.add(list1);
        mainList.add(list2);
        List<List<Object>> resultList = descartes(mainList);
        System.out.println(resultList);
    }

    private static void example3() {
        List<Integer> list1 = Arrays.asList(1, 2, 3);
        List<Integer> list2 = Arrays.asList(1, 2);
        List<List<?>> mainList = new ArrayList<>();
        mainList.add(list1);
        mainList.add(list2);
        List<List<Object>> resultList = descartes(mainList);
        System.out.println(resultList);
    }

    public static List<List<Object>> descartes(Collection<?>... mainList) {
        return descartes(Arrays.asList(mainList));
    }

    // TODO 目前无法实现，返回值类型是一个确定的类型
    public static List<List<Object>> descartes(List<? extends Collection<?>> mainList) {
        List<List<Object>> resultList = new ArrayList<>();
        descartesRecursion(mainList, 0, new ArrayList<>(), resultList);
        return resultList;
    }

    /**
     * 递归求笛卡尔积
     *
     * @param mainList   被求解的集合
     * @param index      中间值-当前操作的mainList下标
     * @param tempList   中间值-结果的一行
     * @param resultList 结果集合
     */
    public static void descartesRecursion(
            List<? extends Collection<?>> mainList,
            int index,
            List<Object> tempList,
            List<List<Object>> resultList) {
        if (index == mainList.size() - 1) { // 终止条件，到达最后一层
            for (Object list : mainList.get(index)) {
                List<Object> continueTempList = new ArrayList<>(tempList);
                continueTempList.add(list);
                resultList.add(continueTempList);
            }
        } else {
            for (Object list : mainList.get(index)) {
                List<Object> continueTempList = new ArrayList<>(tempList);
                continueTempList.add(list);
                descartesRecursion(mainList, index + 1, continueTempList, resultList);
            }
        }
    }


//    @SafeVarargs
//    public static <T> List<List<? extends T>> descartes(Collection<? extends T>... mainList) {
//        return descartes(Arrays.asList(mainList));
//    }
//
//    public static <T> List<List<? extends T>> descartes(List<? extends Collection<? extends T>> mainList) {
//        List<List<? extends T>> resultList = new ArrayList<>();
//        descartesRecursion(mainList, 0, new ArrayList<>(), resultList);
//        return resultList;
//    }
//
//    /**
//     * 递归求笛卡尔积
//     *
//     * @param mainList   被求解的集合
//     * @param index      中间值-当前操作的mainList下标
//     * @param tempList   中间值-结果的一行
//     * @param resultList 结果集合
//     */
//    public static <T> void descartesRecursion(
//            List<? extends Collection<? extends T>> mainList,
//            int index,
//            List<T> tempList,
//            List<List<? extends T>> resultList) {
//        if (index == mainList.size() - 1) { // 终止条件，到达最后一层
//            for (T list : mainList.get(index)) {
//                List<T> continueTempList = new ArrayList<>(tempList);
//                continueTempList.add(list);
//                resultList.add(continueTempList);
//            }
//        } else {
//            for (T list : mainList.get(index)) {
//                List<T> continueTempList = new ArrayList<>(tempList);
//                continueTempList.add(list);
//                descartesRecursion(mainList, index + 1, continueTempList, resultList);
//            }
//        }
//    }


}


